package com.atguigu.spzx.cart.service.Impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.cart.service.CartService;
import com.atguigu.spzx.common.Interceptor.SpzxUserInfoInterceptor;
import com.atguigu.spzx.common.Interceptor.UserLoginAuthInterceptor;
import com.atguigu.spzx.common.exception.GuiguException;
import com.atguigu.spzx.common.util.AuthContextUtil;
import com.atguigu.spzx.feign.product.ProductFeignClient;
import com.atguigu.spzx.model.entity.h5.CartInfo;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.entity.user.UserInfo;
import com.atguigu.spzx.model.vo.common.Result;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author syh
 * @create 2023-09-02 11:16
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
//    private RedisTemplate<String , String> redisTemplate;
    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Resource
    ProductFeignClient productFeignClient;

//    private String getCartKey(Long userId) {
//        //定义key user:cart:userId
//        return "user:cart:" + userId;
//    }
    @Override
    public void addToCart(Long skuId, Integer count) {
//// 获取当前登录用户的id
//        Long userId = AuthContextUtil.getUserInfo().getId();
//        String cartKey = getCartKey(userId);
//
//        //获取缓存对象
//        Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));
//        CartInfo cartInfo = null ;
//        if(cartInfoObj != null) {       //  如果购物车中有该商品，则商品数量 相加！
//            cartInfo = JSON.parseObject(cartInfoObj.toString() , CartInfo.class) ;
//            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
//            cartInfo.setIsChecked(1);
//            cartInfo.setUpdateTime(new Date());
//        }else {
//
//            // 当购物车中没用该商品的时候，则直接添加到购物车！
//            cartInfo = new CartInfo();
//
//            // 购物车数据是从商品详情得到 {skuInfo}
//            ProductSku productSku = productFeignClient.getBySkuId(skuId).getData() ;
//            cartInfo.setCartPrice(productSku.getSalePrice());
//            cartInfo.setSkuNum(skuNum);
//            cartInfo.setSkuId(skuId);
//            cartInfo.setUserId(userId);
//            cartInfo.setImgUrl(productSku.getThumbImg());
//            cartInfo.setSkuName(productSku.getSkuName());
//            cartInfo.setIsChecked(1);
//            cartInfo.setCreateTime(new Date());
//            cartInfo.setUpdateTime(new Date());
//
//        }
//
//        // 将商品数据存储到购物车中
//        redisTemplate.opsForHash().put(cartKey , String.valueOf(skuId) , JSON.toJSONString(cartInfo));
//        ProductSku productSku = productFeignClient.findSkuBySkuId(skuId).getData();
//        System.out.println(productSku);
        UserInfo userInfo = SpzxUserInfoInterceptor.THREAD_LOCAL.get();
        //1、查询用户的购物车
        String cartKey = "cart:user:" + userInfo.getId();
        //购物车hash结构存储 skuId -> CartInfo
        BoundHashOperations<String, String, String> hashOps =
                stringRedisTemplate.boundHashOps(cartKey);
        //2、判断是否存在skuId的购物项
        String cartInfoJson = hashOps.get(String.valueOf(skuId));
        CartInfo cartInfo = null;
        if (StringUtils.isEmpty(cartInfoJson)) {
            //不存在 新创建购物项保存
            cartInfo = new CartInfo();
            //查询sku对应的商品数据
            ProductSku productSku = productFeignClient.findSkuBySkuId(skuId).getData();
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setIsChecked(1); //默认选中
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setSkuNum(count.longValue());
            cartInfo.setUserId(userInfo.getId());
            cartInfo.setCreateTime(new Date());
        } else {
            //存在  数量+count
            cartInfo = JSON.parseObject(cartInfoJson, CartInfo.class);
            cartInfo.setSkuNum(cartInfo.getSkuNum() + count);
        }
        cartInfo.setUpdateTime(new Date());
        //新增或者更新
        hashOps.put(String.valueOf(skuId), JSON.toJSONString(cartInfo));



    }

    @Override
    public List<CartInfo> cartList() {
        BoundHashOperations<String, String, String> hashOps = getRedisCart();
        if(hashOps.size()==0){
            return null;
        }
        //2、获取hash中的value值集合  转为CartInfo的集合返回
        List<CartInfo> cartInfoList = hashOps.values().stream()
                .map(str -> JSON.parseObject(str, CartInfo.class))
                .collect(Collectors.toList());
        return cartInfoList;
    }

    @Override
    public void checkCart(Long skuId, Integer status) {
        BoundHashOperations<String, String, String> cart = getRedisCart();
        String cartInfoJson = cart.get(skuId.toString());
        if(StringUtils.isEmpty(cartInfoJson)){
            throw new GuiguException(ResultCodeEnum.UNKNOW_ERROR);
        }
        CartInfo cartInfo = JSON.parseObject(cartInfoJson, CartInfo.class);
        //更新选中状态
        cartInfo.setIsChecked(status);
        //设置到redis中
        cart.put(skuId.toString() , JSON.toJSONString(cartInfo));
    }

    @Override
    public void allCheckCart(Integer status) {
        BoundHashOperations<String, String, String> cart = getRedisCart();

        //遍历所有的entry，将value值cartInfo选中状态改为status 然后put到hash中
        if(cart.size()==0){
            return;
        }
        cart.entries().forEach((skuId,cartInfoJson)->{
            CartInfo cartInfo = JSON.parseObject(cartInfoJson, CartInfo.class);
            cartInfo.setIsChecked(status);
            cart.put(skuId , JSON.toJSONString(cartInfo));
        });
    }

    @Override
    public void deleteCartInfo(Long skuId) {
        BoundHashOperations<String, String, String> cart = getRedisCart();
        cart.delete(String.valueOf(skuId));
    }

    @Override
    public void clearCart() {
        BoundHashOperations<String, String, String> cart = getRedisCart();
        cart.delete(cart.keys().toArray());
    }

    @Override
    public List<CartInfo> getAllCheckedCartInfo() {
        // Map<skuId,cartInfoJsonStr>
        //1、根据userId获取他的购物车
        BoundHashOperations<String, String, String> hashOps = getRedisCart();
        if(hashOps.size()==0){
            return null;
        }
        //2、获取hash中的value值集合  转为CartInfo的集合返回
        List<CartInfo> cartInfoList = hashOps.values().stream()
                .map(str -> JSON.parseObject(str, CartInfo.class))
                .filter(cartInfo -> cartInfo.getIsChecked().equals(1))
                .collect(Collectors.toList());
        return cartInfoList;
    }

    @Override
    public void deleteCheckedCartInfo() {
        //1、获取用户的购物车
        BoundHashOperations<String, String, String> cart = getRedisCart();
        //2、删除购物车中选中的购物项
        cart.entries().forEach((skuIdStr ,  cartInfoStr)->{
            //判断正在遍历的购物项是否被选中
            CartInfo cartInfo = JSON.parseObject(cartInfoStr, CartInfo.class);
            if(cartInfo.getIsChecked().intValue()==1){
                //删除选中的购物项
                cart.delete(skuIdStr);
            }
        });
    }

//    @Override
//    public List<CartInfo> getCartList() {
//        // 获取当前登录的用户信息
//        Long userId = AuthContextUtil.getUserInfo().getId();
//        String cartKey = this.getCartKey(userId);
//
//        // 获取数据
//        List<Object> cartInfoList = redisTemplate.opsForHash().values(cartKey);
//
//        if (!CollectionUtils.isEmpty(cartInfoList)) {
//            List<CartInfo> infoList = cartInfoList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
//                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
//                    .collect(Collectors.toList());
//            return infoList ;
//        }
//
//        return new ArrayList<>() ;

    private BoundHashOperations<String, String, String> getRedisCart() {
    UserInfo userInfo = SpzxUserInfoInterceptor.THREAD_LOCAL.get();
    String cartKey = "cart:user:" + userInfo.getId();
    BoundHashOperations<String, String, String> hashOps =
            stringRedisTemplate.boundHashOps(cartKey);
    return hashOps;
}
//    }

}
